﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.DynamicData;
using System.Web.SessionState;
using System.Web.UI;
using NotAClue.ComponentModel.DataAnnotations;
using NotAClue.Web;
using System.ComponentModel;

namespace NotAClue.Web.DynamicData
{
    public static class FilterHistoryExtensionMethods
    {
        /// <summary>
        /// Adds the filters current value to the session.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="column">The column.</param>
        /// <param name="value">The value.</param>
        public static void AddFilterValueToSession(this Page page, MetaColumn column, Object value)
        {
            Dictionary<String, Object> filterValues;
            var objectName = column.Table.DataContextPropertyName;
            var obj = page.Session[objectName];

            // get correct column name 
            var columnName = column.Name;
            if (column is MetaForeignKeyColumn)
                columnName = ((MetaForeignKeyColumn)column).ForeignKeyNames.ToCommaSeparatedString();

            // check to see if we already have a session object
            if (obj != null && obj is Dictionary<String, Object>)
                filterValues = (Dictionary<String, Object>)obj;
            else
                filterValues = new Dictionary<String, Object>();

            // add new filter value to session object
            if (filterValues.Keys.Contains(columnName))
                filterValues[columnName] = value;
            else
                filterValues.Add(columnName, value);

            // add back to session
            if (obj != null)
                obj = filterValues;
            else
                page.Session.Add(objectName, filterValues);
        }

        /// <summary>
        /// Adds the custom filter's current value to the session state.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="table">The table.</param>
        /// <param name="pageField">The page field.</param>
        /// <param name="value">The value.</param>
        public static void AddCustomFilterValueToSession(this Page page, MetaTable table, String pageField, Object value)
        {
            var objectName = table.DataContextPropertyName;
            Dictionary<String, Object> filterValues;
            var obj = page.Session[objectName];

            if (obj != null && obj is Dictionary<String, Object>)
                filterValues = (Dictionary<String, Object>)obj;
            else
                filterValues = new Dictionary<String, Object>();

            if (filterValues.Keys.Contains(pageField))
                filterValues[pageField] = value;
            else
                filterValues.Add(pageField, value);

            // add back to session
            if (obj != null)
                obj = filterValues;
            else
                page.Session.Add(objectName, filterValues);
        }

        /// <summary>
        /// Gets the filter values from session.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="table">The table.</param>
        /// <param name="defaultValues">The default values.</param>
        /// <returns>An IDictionary of filter values from the session.</returns>
        public static IDictionary<String, Object> GetFilterValuesFromSession(this Page page, MetaTable table, IDictionary<String, Object> defaultValues)
        {
            var queryString = new StringBuilder();
            var objectName = table.DataContextPropertyName;
            var obj = page.Session[objectName];

            foreach (var column in table.Columns)
            {
                var defaultValue = column.GetAttribute<DefaultValueAttribute>();
                if (defaultValue != null)
                {
                    if (!defaultValues.Keys.Contains(column.Name))
                        defaultValues.Add(column.Name, defaultValue.Value);
                }
            }

            if (obj == null || !(obj is Dictionary<String, Object>))
                return defaultValues;

            var filterValues = new Dictionary<String, Object>();
            var sessionFilterValues = (Dictionary<String, Object>)obj;
            if (sessionFilterValues != null)
            {
                foreach (var entry in sessionFilterValues.Where(d => !d.Value.ToString().Contains("|")))
                {
                    filterValues.Add(entry.Key, entry.Value);
                }
                foreach (string key in defaultValues.Keys)
                {
                    if ((!filterValues.Keys.Contains(key) || filterValues[key] == null))
                        filterValues.Add(key, defaultValues[key]);
                    else
                        filterValues[key] = defaultValues[key];
                }
            }
            return filterValues;
        }

        /// <summary>
        /// Gets the filter value from session.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="column">The column.</param>
        /// <returns></returns>
        public static String GetFilterValueFromSession(this Page page, MetaColumn column)
        {
            var filterValue = new StringBuilder();
            var objectName = column.Table.DataContextPropertyName;
            var obj = page.Session[objectName];

            if (obj != null && obj is Dictionary<String, Object>)
            {
                var filterValues = (Dictionary<String, Object>)obj;
                if (filterValues.Keys.Contains(column.Name))
                    return filterValues[column.Name].ToString();
            }

            return String.Empty;
        }

        /// <summary>
        /// Gets the filter value from session.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="column">The column.</param>
        /// <returns></returns>
        public static Object GetFilterValueFromSession(this Page page, MetaTable table, String pageField)
        {
            var filterValue = new StringBuilder();
            var objectName = table.DataContextPropertyName;
            var obj = page.Session[objectName];

            if (obj != null && obj is Dictionary<String, Object>)
            {
                var filterValues = (Dictionary<String, Object>)obj;
                if (filterValues.Keys.Contains(pageField))
                    return filterValues[pageField];
            }

            return null;
        }

        /// <summary>
        /// Clears the table filters.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="table">The table.</param>
        public static void ClearTableFilters(this Page page, MetaTable table)
        {
            var objectName = table.DataContextPropertyName;

            if (page.Session[objectName] != null)
                page.Session[objectName] = null;
        }
    }
}